<?php

/*
 *  Copyright (C) 2012 etpass
 * 
 *  author:chl <chenhl, chenhl@etpass.com>
 *  date:2012-8-20
 *  encoding:UTF-8
 *  filename:access_control.class.php
 *  link:http://www.etpass.com
 */

/**
 * 
 *
 * @author etpasse
 */
require_rewrite(SYSTEM_PATH . 'lib/cache/MemoryCache.php');
require_rewrite(SYSTEM_PATH . 'lib/cache/ApcCache.php');
class access_control {

    private $file; //要控制的文件 $_SERVER['PHP_SELF']
    private $ip;
    private $ip_self;
    private $file_id;
    private $ttl = 60; // m 
    private $control_num = 15;
    private $cont_ttl = 172800;
    private $control_ip; // 受控制的ip 
    private $cache;
    private $m_cache;
    private $c_ids;
    private $login_error_key;

    public function __construct($file = '') {
//        $_SERVER["SCRIPT_FILENAME"]
        !$file && $file = $_SERVER['SCRIPT_FILENAME'];

        $this->file = $file;
        $this->ip_self = Handler_http::getIP();
        $this->ip = Handler_tool::ip2long($this->ip_self);
        
        $this->m_cache = MemoryCache::getInstance();
        $this->cache = new ApcCache();
//        $this->cache = MemoryCache::getInstance();
        $this->file_id = md5($this->file . $this->ip);
        $this->c_ids = 'list_ips';
        $this->login_error_key = md5($this->ip);
    }

    /**
     * 一段时间访问次数控制
     * @return boolean 
     */
    public function control_ip() {
        //取得禁止ip列表
        $ips = $this->getips();
        if (in_array($this->ip, $ips)) {//在列表
            return TRUE;
        } else {//不在列表
            $this->init_control(); //统计访问次数
            if ($this->ip == $this->control_ip) {//访问次数异常
                return TRUE;
            }
        }
        return FALSE;
    }

    /**
     * 提交验证码后，清除当前ip的限制 
     */
    public function clear_control() {

        $list_ips = $this->getips();
        unset($list_ips[$this->ip]);
        $this->cache->set($this->c_ids, $list_ips, $this->cont_ttl);
         
        if($this->cache->delete($this->file_id)){
            return TRUE;
        }else{
            $this->cache->set($this->file_id, 1, $this->ttl);
            Log_File::writeHotelLog('control_post',  $this->ip_self.'-'.$this->file);//删除失败写日志
            return TRUE;
        }
//        return TRUE;
    }

    /**
     * 设置一段时间内登录失败次数 
     */
    public function set_login_error_times() {
        $login_err = $this->get_login_error_times();
        if ($login_err <= 5) {
            $login_err++;
            $this->m_cache->set($this->login_error_key, $login_err, 3600);
        }
        return $login_err;
    }

    /**
     * 一段时间内登录失败次数 
     */
    public function get_login_error_times() {
        $login_err = $this->m_cache->get($this->login_error_key);
        !$login_err && $login_err = 0;
        return $login_err;
    }

    /**
     * 删除登录失败次数 现在没有用到
     */
    public function del_login_error_times() {

        return $this->m_cache->delete($this->login_error_key);
    }

    /**
     * 访问控制数据存储到memcache 文件+ip 为id 会生成很多小文件
     * 
     */
    private function init_control() {

        $controls = intval($this->cache->get($this->file_id));
        !$controls && $controls = 0;
        if ($controls < $this->control_num) {
            $controls++;
            $this->cache->set($this->file_id, $controls, $this->ttl);
        } else {//访问次数异常，设置禁止ip并加入到禁止列表，
            $this->control_ip = $this->ip;

            $this->setips();
        }
    }

    public function getips() {
        $list_ips = $this->cache->get($this->c_ids);
        !$list_ips && $list_ips = array();
        return $list_ips;
    }

    private function setips() {
        $list_ips = $this->getips();
        $list_ips[$this->ip] = $this->ip;
        $this->cache->set($this->c_ids, $list_ips, $this->cont_ttl);
    }

}

?>
